class Bluetooth {
  static devices = []

  // IOS系统获取蓝牙设备的MAC地址方法
  static array2String(buffer) {
    let hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    })
    return `${hexArr[7]}:${hexArr[6]}:${hexArr[5]}:${hexArr[2]}:${hexArr[1]}:${hexArr[0]}`
  }

  // 处理搜索到的蓝牙列表
  static inArray(arr, key, val) {
    for (let i = 0; i < arr.length; i++) {
      if (arr[i][key] === val) {
        return i
      }
    }
    return -1
  }
  // 16进制的字符串 转换为整数
  static hex2int(hex) {
    var len = hex.length,
      a = new Array(len),
      code;
    for (var i = 0; i < len; i++) {
      code = hex.charCodeAt(i);
      if (48 <= code && code < 58) {
        code -= 48;
      } else {
        code = (code & 0xdf) - 65 + 10;
      }
      a[i] = code;
    }

    return a.reduce(function (acc, c) {
      acc = 16 * acc + c;
      return acc;
    }, 0);
  }
  // 字符串转十六进制
  static stringToHexCharCode(string) {
    if (string === '')
      return ''
    let hexCharCode = []
    for (let i = 0; i < string.length; i++) {
      hexCharCode.push((string.charCodeAt(i)).toString(16))
    }
    return hexCharCode.join('')
  }
  // 十六进制 转 ArrayBuffer(硬件只接收该格式数据),通过蓝牙向硬件设备写入数据
  static hexStringToArrayBuffer(hexString) {
    let codeLength = hexString.length / 2 // 因为协议中一个字节占两个字符的控制命令,codeLength为命令字节数
    const buffer = new ArrayBuffer(codeLength)
    const dataView = new DataView(buffer)
    for (let i = 0; i < codeLength; i++) {
      dataView.setUint8(i, '0x' + hexString.substring(i * 2, i * 2 + 2))
    }
    return buffer
  }
  // ArrayBuffer(连接的蓝牙设备广播出来的信息)转16进制字符串
  static ab2hex(buffer) {
    let hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
      function (bit) {
        return ('00' + bit.toString(16)).slice(-2)
      }
    )
    return hexArr.join('');
  }
  // ArrayBuffer类型数据转Ascii 字符编码,字集码
  static ab2Ascii(buffer) {
    var str = Array.prototype.map.call(
      new Uint8Array(buffer),
      function (bit) {
        return String.fromCharCode(bit);
      }
    )
    return str.join('');
  }
  // 开启蓝牙适配器
  static openBluetooth() {
    return new Promise((resolve, reject) => {
      wx.openBluetoothAdapter({
        success: (res) => {
          resolve(res)
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }
  // 开始搜索附近的蓝牙外围设备
  static startBluetoothDevicesDiscovery() {
    return new Promise((resolve, reject) => {
      wx.startBluetoothDevicesDiscovery({
        // services: ['TJL-BL-SKIP'],  // 要搜索的蓝牙设备名称(UUID)
        success: (res) => {
          resolve(res)
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }
  // 监听到新设备的回调事件
  static onBluetoothDeviceFound(func) {
    wx.onBluetoothDeviceFound((res) => {
      func && func(res.devices, this.devices)
    })
  }
  // 只获取蓝牙列表,其余连接蓝牙等信息都不暴露出去
  static foundBluetoothDevices(func) {
    this.openBluetooth().then((res) => {
      this.startBluetoothDevicesDiscovery().then((res) => {
        this.onBluetoothDeviceFound(func)
      }).catch((err) => {
        console.log(err)
      })
    }).catch((err) => {
      console.log(err)
    })
  }
  // 停止搜索扫描附近蓝牙设备
  static stopBluetoothDevicesDiscovery() {
    return new Promise((resolve, reject) => {
      wx.stopBluetoothDevicesDiscovery({
        success: (res) => {
          resolve(res)
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }
  // 与蓝牙设备建立连接
  static createBLEConnection(deviceId) {
    return new Promise((resolve, reject) => {
      wx.createBLEConnection({
        deviceId,
        success: (res) => {
          resolve(res)
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }
  // 获取连接的低功耗蓝牙设备的服务uuid(service)
  static getBLEDeviceServices(deviceId) {
    return new Promise((resolve, reject) => {
      wx.getBLEDeviceServices({
        deviceId,
        success: (res) => {
          resolve(res)
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }
  // 根据连接蓝牙设备的服务UUID获取该蓝牙设备的(读写)特征值
  static getBLEDeviceCharacteristics(deviceId, serviceId) {
    return new Promise((resolve, reject) => {
      wx.getBLEDeviceCharacteristics({
        deviceId,
        serviceId,
        success: (res) => {
          resolve(res)
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }
  // 启用蓝牙低功耗设备特征值变化时的 notify 功能，订阅特征
  static notifyBLECharacteristicValueChange(deviceId, serviceId, characteristicId) {
    return new Promise((resolve, reject) => {
      wx.notifyBLECharacteristicValueChange({
        deviceId,
        serviceId,
        characteristicId,
        state: true,
        success: (res) => {
          resolve(res)
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }
  // 向蓝牙低功耗设备特征值中写入二进制数据
  static writeBLECharacteristicValue(deviceId, serviceId, characteristicId, value) {
    return new Promise((resolve, reject) => {
      wx.writeBLECharacteristicValue({
        deviceId,
        serviceId,
        characteristicId,
        value,
        success: (res) => {
          resolve(res)
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }
  // 读取蓝牙低功耗设备特征值的二进制数据。注意：必须设备的特征支持 read 才可以成功调用
  static readBLECharacteristicValue(deviceId, serviceId, characteristicId) {
    return new Promise((resolve, reject) => {
      wx.readBLECharacteristicValue({
        deviceId,
        serviceId,
        characteristicId,
        success: (res) => {
          resolve(res)
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }
  // 监听蓝牙低功耗设备的特征值变化事件
  static onBLECharacteristicValueChange() {
    return new Promise((resolve, reject) => {
      wx.onBLECharacteristicValueChange((res) => {
        console.log('特征值变化事件', res)
        // res = this.ab2hex(res.value)
        // debugger
        res.value = this.ab2hex(res.value)
        resolve(res)
      })
    })
  }
  // 断开与蓝牙低功耗设备的连接
  static closeBLEConnection(deviceId) {
    return new Promise((resolve, reject) => {
      wx.closeBLEConnection({
        deviceId,
        success: (res) => {
          resolve(res)
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }
  // 关闭蓝牙模块,调用该方法将断开所有已建立的连接并释放系统资源
  static closeBluetoothAdapter() {
    return new Promise((resolve, reject) => {
      wx.closeBluetoothAdapter({
        success: (res) => {
          resolve(res)
        },
        fail: (err) => {
          reject(err)
        }
      })
    })
  }

}

export default Bluetooth